/**
 * @description 构建容器组件模板
 */

import {
  DesTableColumns,
  DesOperationButton,
  DesButtonGroup
} from "/@/components/fromDesigner/constants";
import { buildFieldWidget } from "./field";
import { getElAttr } from "./property";
import { DesFormWidgetMethods, DesFormWidgetParams } from "../interface";

const containerTemplate = {
  grid: (params) => {
    let { widget, formConfig } = params;
    let elAttr = getElAttr(params);
    return `<el-row ${elAttr.customClass}>
      ${widget.children
        ?.map((col) => {
          let { span, md, sm, xs, offset, push, pull, customClass } = getElAttr(
            {
              widget: col,
              formConfig
            }
          );
          return `<el-col ${customClass} ${span} ${md} ${sm} ${xs} ${offset} ${push} ${pull}>
          ${col.children
            ?.map((child) => {
              if (child.category === "container") {
                return buildContainerWidget({ widget: child, formConfig });
              } else {
                return buildFieldWidget({ widget: child, formConfig });
              }
            })
            .join("\n")}
        </el-col>`;
        })
        .join("\n")}
    </el-row>`;
  },

  table: (params) => {
    let { widget, formConfig } = params;
    let elAttr = getElAttr(params);
    return `<table ${elAttr.customClass}>
    <tbody>
    ${widget.children
      ?.map((rows) => {
        return ` <tr>
      ${rows.children
        ?.map((col) => {
          let { colspan, rowspan, customClass } = getElAttr({
            widget: col,
            formConfig
          });
          return ` <td ${customClass} ${colspan} ${rowspan}>
            ${col.children
              ?.map((child) => {
                if (child.category === "container") {
                  return buildContainerWidget({ widget: child, formConfig });
                } else {
                  return buildFieldWidget({ widget: child, formConfig });
                }
              })
              .join("\n")}
          </td>`;
        })
        .join("\n")}
    </tr>`;
      })
      .join("\n")}
   </tbody>
   </table>`;
  },

  card: (params) => {
    let { widget, formConfig } = params;
    let { label, shadow, cardWidth, customClass } = getElAttr(params);
    return `<el-card ${customClass} ${cardWidth} ${shadow}>
    <template #header>
      <div class="card-header">
        <span>${label}</span>
      </div>
      ${widget.children
        ?.map((child) => {
          if (child.category === "container") {
            return buildContainerWidget({ widget: child, formConfig });
          } else {
            return buildFieldWidget({ widget: child, formConfig });
          }
        })
        .join("\n")}
      </template>
    </el-card>`;
  },

  tabs: (params) => {
    let { widget, formConfig } = params;
    let { onTabClick, name } = widget.options;
    let elAttr = getElAttr(params);
    let onTabClickEvent = onTabClick ? `@click="${name}TabClick"` : "";
    return `<el-tabs ${elAttr.customClass} ${onTabClickEvent}>
      ${widget.children
        ?.map((tab) => {
          let { label, disabled } = getElAttr(params);
          return `<el-tabs-pane ${label} ${disabled}>
          ${tab.children
            ?.map((child) => {
              if (child.category === "container") {
                return buildContainerWidget({ widget: child, formConfig });
              } else {
                return buildFieldWidget({ widget: child, formConfig });
              }
            })
            .join("\n")}
          </el-tabs-pane>`;
        })
        .join("\n")}
    </el-tabs>`;
  },

  "data-table": (params) => {
    let { widget } = params;
    let {
      tableColumns,
      operationButtons,
      showCheckBox,
      showIndex,
      small,
      showPagination,
      name,
      pagination,
      onSelect,
      onSelectAll,
      onSelectionChange,
      onCellClick,
      onRowClick,
      onHeaderClick,
      onSortChange,
      onFilterChange,
      onExpandChange,
      onPageSizeChange,
      onCurrentPageChange
    } = widget.options;
    let {
      tableWidth,
      border,
      fit,
      height,
      showHeader,
      customClass,
      highlightCurrentRow,
      operationLabel,
      operationWidth,
      operationFixed,
      operationAlign
    } = getElAttr(params);
    // 事件
    let onSelectEvent = onSelect ? `@select="${name}Select "` : "";
    let onSelectAllEvent = onSelectAll ? `@select-all="${name}SelectAll"` : "";
    let onSelectionChangeEvent = onSelectionChange
      ? `@selection-change="${name}SelectionChange"`
      : "";
    let onCellClickEvent = onCellClick ? `@cell-click="${name}CellClick"` : "";
    let onRowClickEvent = onRowClick ? `@row-click="${name}RowClick"` : "";
    let onHeaderClickEvent = onHeaderClick
      ? `@header-click="${name}ClickEvent"`
      : "";
    let onSortChangeEvent = onSortChange
      ? `@sort-change="${name}SortChange"`
      : "";
    let onFilterChangeEvent = onFilterChange
      ? `@filter-change="${name}FilterChange"`
      : "";
    let onExpandChangeEvent = onExpandChange
      ? `@expand-change="${name}ExpandChange"`
      : "";
    let onPageSizeChangeEvent = onPageSizeChange
      ? `@size-change="${name}PageSizeChange"`
      : "";
    let onCurrentPageChangeEvent = onCurrentPageChange
      ? `@current-change="${name}CurrentPageChange"`
      : "";

    let colIndexHtml = showIndex
      ? ` <el-table-column type="index" width="50" align="center"></el-table-column>`
      : "";
    let colCheckBoxHtml = showCheckBox
      ? `<el-table-column type="selection" width="50" align="center"></el-table-column>`
      : "";
    let buttonTemplateHtml = `
    <el-table-column ${operationLabel} ${operationWidth} ${operationAlign} ${operationFixed}>
      <template #default>
      ${operationButtons
        .map((btn: DesOperationButton) => {
          let {
            disabled,
            label,
            round,
            size,
            text,
            type,
            link,
            onTableColumnClick
          } = btn;
          let onTableColumnClickEvent = onTableColumnClick
            ? `@click="${btn.name}TableColumnClick"`
            : "";
          let sizeAttr = size !== "default" ? `size="${size}"` : "";
          let typeAttr = type ? `type="${type}"` : "";
          let disabledAttr = disabled ? "disable" : "";
          let textAttr = text ? "text" : "";
          let roundAttr = round ? "round" : "";
          let linkAttr = link ? "link" : "";
          return `<el-button ${typeAttr} ${sizeAttr} ${linkAttr} ${textAttr} ${roundAttr}
          ${disabledAttr} ${onTableColumnClickEvent} >${label}</el-button> `;
        })
        .join("\n")}
      </template>
    </el-table-column>
    `;

    let paginationHtml = "";
    if (showPagination) {
      let smallAttr = small ? "small" : "";
      let { pageSizes, total } = pagination || {};
      let pageSizesAttr = pageSizes
        ? `:page-sizes="${JSON.stringify(pageSizes)}"`
        : "";
      let totalAttr = total ? `:total="${total}"` : "";
      paginationHtml = `<el-pagination ${smallAttr} ${pageSizesAttr}
      ${onPageSizeChangeEvent} ${onCurrentPageChangeEvent} ${totalAttr}
      layout="total, sizes, prev, pager, next, jumper" />`;
    }

    return `
    <el-table ${customClass} :data="tableData" ${tableWidth} ${border} ${fit} ${height} ${showHeader} ${highlightCurrentRow}
    ${onSelectEvent} ${onSelectAllEvent} ${onSelectionChangeEvent} ${onCellClickEvent} ${onRowClickEvent}
    ${onHeaderClickEvent} ${onSortChangeEvent} ${onFilterChangeEvent} ${onExpandChangeEvent}>
    ${colIndexHtml}
    ${colCheckBoxHtml}
    ${tableColumns
      .map((col: DesTableColumns) => {
        let { align, label, minWidth, fixed, prop, sortable } = col;
        let alignAttr = align && align != "left" ? `align="${align}"` : "";
        let labelAttr = label ? `label="${label}"` : "";
        let minWidthAttr = minWidth ? `min-width="${minWidth}"` : "";
        let propAttr = prop ? `prop="${prop}"` : "";
        let sortableAttr = sortable ? `sortable` : "";
        let fixedAttr = fixed ? `fixed="${fixed}"` : "";
        return `<el-table-column ${propAttr} ${alignAttr} 
          ${labelAttr} ${minWidthAttr} ${fixedAttr} ${sortableAttr}>
        </el-table-column>`;
      })
      .join("\n")}
    ${buttonTemplateHtml}
    </el-table>
    ${paginationHtml}
    `;
  },

  "data-tree": (params) => {
    let { widget } = params;
    let {
      name,
      showCheckbox,
      showCheckAllOrCancelAll,
      showFilter,
      onNodeClick,
      onNodeCheck,
      onCheckChange
    } = widget.options;

    let onNodeClickEvent = onNodeClick ? `@node-click="${name}NodeClick"` : "";
    let onNodeCheckEvent = onNodeCheck ? `@check="${name}NodeCheck"` : "";
    let onCheckChangeEvent = onCheckChange
      ? `@check-change="${name}CheckChange"`
      : "";

    let {
      nodeKey,
      draggable,
      defaultExpandAll,
      lazy,
      props,
      showLinkage,
      customClass
    } = getElAttr(params);
    const searchInputHtml = showFilter ? "" : "showFilter";
    const expandOrRetractHtml = showCheckbox ? "" : "";
    const selectAllHtml = showCheckAllOrCancelAll ? "" : "";
    const treeDefaultTemplateHtml = `<template #default="{ node }">
    <div>{{ node.label }}</div>
    <div class="ex-tree-buttons">
      <el-button type="primary" link>添加</el-button>
      <el-button type="primary" link>删除</el-button>
    </div>
    </template>`;
    return `
    ${searchInputHtml}
    ${expandOrRetractHtml}
    ${selectAllHtml}
    <el-tree ${customClass} ref="treeRef" :data="treeData" ${nodeKey} ${draggable} 
      ${defaultExpandAll} ${lazy} ${props} ${showLinkage} ${onNodeClickEvent} 
      ${onCheckChangeEvent} ${onNodeCheckEvent}> ${treeDefaultTemplateHtml}
    </el-tree>
    `;
  },

  "button-group": (params) => {
    let { widget } = params;
    let { buttonGroups } = widget.options;
    let { customClass } = getElAttr(params);
    return `<el-button-group ${customClass}>
    ${buttonGroups
      .map((btn: DesButtonGroup) => {
        let { disabled, label, round, text, type, link, onClick } = btn;
        let onClickEvent = onClick ? `@click="${btn.name}Click"` : "";
        let typeAttr = type ? `type="${type}"` : "";
        let disabledAttr = disabled ? "disable" : "";
        let textAttr = text ? "text" : "";
        let roundAttr = round ? "round" : "";
        let linkAttr = link ? "link" : "";
        return `<el-button ${typeAttr} ${linkAttr} ${textAttr} ${roundAttr}
        ${disabledAttr} ${onClickEvent} >${label}</el-button> `;
      })
      .join("\n")}
    </el-button-group>`;
  },

  "object-group": (params) => {
    let { widget, formConfig } = params;
    let { customClass } = getElAttr(params);
    // TODO:模板待处理
    return `<div> ${customClass}
    ${widget.children
      ?.map((child) => {
        if (child.category === "container") {
          return buildContainerWidget({ widget: child, formConfig });
        } else {
          return buildFieldWidget({ widget: child, formConfig });
        }
      })
      .join("\n")}
    </div>`;
  },

  "sub-form": (params) => {
    let { widget, formConfig } = params;
    let { labelAlign, showRowIndex } = widget.options;
    let {
      headerAddBtn,
      columnOperationBtn,
      isPositionLeft,
      subFormList,
      customClass
    } = getSubFormTemplateFragment(params);

    // 序号
    let rowOnText = showRowIndex
      ? !isPositionLeft
        ? `<th><div class="row-on-header">序号</div></th>`
        : ""
      : "";

    let rowOnIndexText = showRowIndex
      ? !isPositionLeft
        ? `<td><div class="row-on-column">#{{ index + 1 }}</div></td>`
        : ""
      : "";

    // 标题
    let fieldLabel = widget.children
      ?.map((child) => {
        let { columnWidth, label } = child.options;
        let style = columnWidth ? `style="width:${columnWidth}"` : "";
        return `<th><div class="row-field-header ${labelAlign}" ${style}>${label}</div></th>`;
      })
      .join("\n");

    let filedLabelLeft = isPositionLeft ? fieldLabel : "";
    let filedLabelRight = !isPositionLeft ? fieldLabel : "";

    // 组件模板
    let fieldWidget = widget.children
      ?.map((child) => {
        let { columnWidth } = child.options;
        let style = columnWidth ? `style="width:${columnWidth}"` : "";
        return `<td>
      <div class="row-field-column" ${style}>
        ${buildFieldWidget({ widget: child, formConfig })}
      </div>
    </td>`;
      })
      .join("\n");

    let fieldWidgetRight = !isPositionLeft ? fieldWidget : "";
    let fieldWidgetLeft = isPositionLeft ? fieldWidget : "";

    return `<table class="ex-sub-form-table ${customClass}">
    <tr>
      ${rowOnText}
       ${filedLabelRight}
      <th>
        <div class="row-action-header">
          ${headerAddBtn}
        </div>
      </th>
     ${filedLabelLeft}
    </tr>
    <tr v-for="(subForm, index) of ${subFormList}" :key="index">
      ${rowOnIndexText}
      ${fieldWidgetRight}
      <td>
        ${columnOperationBtn}
      </td>
      ${fieldWidgetLeft}
    </tr>
  </table>`;
  },

  "grid-sub-form": (params) => {
    let { widget, formConfig } = params;
    let {
      rowOnColumn,
      headerAddBtn,
      columnOperationBtn,
      isPositionLeft,
      subFormList,
      customClass
    } = getSubFormTemplateFragment(params);

    let fieldWidget = widget.children
      ?.map((child) => {
        if (child.category === "container") {
          return buildContainerWidget({ widget: child, formConfig });
        } else {
          return buildFieldWidget({ widget: child, formConfig });
        }
      })
      .join("\n");

    let fieldWidgetRight = !isPositionLeft
      ? `<div class="row-field-column field-border-right">
          ${fieldWidget}
          </div>`
      : "";
    let fieldWidgetLeft = isPositionLeft
      ? `<div class="row-field-column">
          ${fieldWidget}
          </div>`
      : "";

    return `<div class="ex-grid-sub-form ${customClass}">
    <div class="row-header">
      ${headerAddBtn}
    </div>
    <div
      class="row-column"
      v-for="(subForm, index) of ${subFormList}"
      :key="index"
    >
      ${rowOnColumn}
      ${fieldWidgetRight}
      ${columnOperationBtn}
      ${fieldWidgetLeft}
    </div>
  </div>`;
  }
} as DesFormWidgetMethods;

function getSubFormTemplateFragment(params: DesFormWidgetParams) {
  let { widget, formConfig } = params;
  let { columnPosition, showRowIndex, name, customClass } = widget.options;
  let isPositionLeft = columnPosition === "left";
  let rowOnIndex = showRowIndex
    ? columnPosition !== "left"
      ? `<div class="row-on-index">#{{ index + 1 }}</div>`
      : ""
    : "";

  return {
    isPositionLeft,
    customClass:
      customClass && customClass.length > 0 ? `${customClass.join(" ")}` : "",
    subFormList: `${formConfig.modelName}.${name}`,
    rowOnColumn: showRowIndex
      ? !isPositionLeft
        ? `<div class="row-on-column">#{{ index + 1 }}</div>`
        : ""
      : "",

    headerAddBtn: `<div class="column-label">操作</div>
    <el-button
      class="column-btn"
      type="primary"
      round
      size="small"
      @click="handleAdd('${name}')"
    >
      新增
    </el-button>`,

    columnOperationBtn: `<div class="row-action-column">
    <el-button
      icon="Plus"
      type="primary"
      plain
      circle
      @click="handleSubFormInset('${name}',index)"
    />
    <el-button
      icon="Delete"
      type="danger"
      plain
      circle
      @click="handleSubFormDelete('${name}',index)"
    />
    ${rowOnIndex}
  </div>`
  };
}

export function buildContainerWidget(params: DesFormWidgetParams): string {
  let { widget } = params;
  return containerTemplate[widget.type] &&
    containerTemplate[widget.type](params)
    ? containerTemplate[widget.type](params)
    : "";
}
